	.file	"calc.c"				// 指明编译的 .c 文件
	.option nopic					// 编译器参数
	.attribute arch, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0"	// 指令集
	.attribute unaligned_access, 0
	.attribute stack_align, 16														// 堆内存对齐
	.text																									// .text 程序段
	.align	1																							// 本程序段不需要对齐
	.globl	_start																				// 将 _start 段设置为全局可见
	.type	_start, @function																// 设置本段的属性为一个函数
_start:							// _start 段开始，程序从这里进入
	addi	sp,sp,-32		// 将当前栈指针向低地址移动 32 个字节，表示在栈中新申请一个 8 个 word 大小的栈
	sd	s0,24(sp)			// 在栈的第六个 word 处储存 s0 寄存器的值
	addi	s0,sp,32		// 将帧缓存地址设置为栈底
	li	a5,19					// 将 a5 寄存器的值设置为 19，即 `uint8_t code = 19`
	sb	a5,-25(s0)		// 将 a5(`code`)的低 8bit 保存到帧缓存地址向下第25字节
	sb	zero,-17(s0)	// 将 0(`i`)的地 8bit 保存到帧缓存地址向下第17字节
	sw	zero,-24(s0)	// 将 0(`sum`) 整个 word 保存到帧缓存地址向下第24字节
	j	.L2							// 跳转到标号 .L2
.L4:								// .L4 标号开始，为第一个 `while` 的循环体
	lbu	a5,-25(s0)		// 从帧缓存地址向下第 25 字节无符号取低字节到 a5，即 `a5 = code`
	sext.w	a4,a5			// 将 a5 符号扩展的结果写入 a4，即 `a4 = SEXT(code)`，因为 `code` 是一个 uint8_t 类型
	lbu	a5,-17(s0)		// 从帧缓存地址向下第 17 字节无符号取低字节到 a5，即 `a5 = i`
	sext.w	a5,a5			// 将 a5 符号扩展的结果写入 a4，即 `a4 = SEXT(i)`，因为 `i` 是一个 uint8_t 类型
	sraw	a5,a4,a5		// a5 = a4 >>s a5，将 a4 算术右移 a5 位的结果写入 a5，即 `a5 = (i << i)`
	sext.w	a5,a5			// 对 a5 做符号扩展
	andi	a5,a5,1			// 将 a5(`i`) 与 1 相与存到 a5，即得到 `a5 = (1 << i)`
	sext.w	a5,a5			// 对 a5 做符号扩展
	beq	a5,zero,.L3		// `if (code & (1 << i))`，不为0则跳转到 .L3
	lbu	a5,-25(s0)		// 从帧缓存地址向下第 25 字节取低字节到 a5，即 `a5 = code`
	sext.w	a4,a5			// 对 a5 做符号扩展，写入 a4
	lbu	a5,-17(s0)		// 从帧缓存地址向下第 17 字节无符号取低字节到 a5，即 `a5 = i`
	sext.w	a5,a5			// 对 a5 做符号扩展
	sllw	a5,a4,a5		// a5 = a4 << a5，即将 a4 逻辑左移 a5 位的结果写入 a5，即 `a5 = code << i`
	sext.w	a5,a5			// 对 a5 做符号扩展
	sext.w	a5,a5			// 对 a5 做符号扩展
	lw	a4,-24(s0)		// 从帧缓存地址向下第 24 字节取四字节到 a4，即 `a4 = sum`
	addw	a5,a4,a5		// a5 = a4 + a5，即 `sum += code << i`
	sw	a5,-24(s0)		// 将 a5 的值存入帧缓存向下第 24 字节处，即储存 `sum` 到缓存中
.L3:								// .L3 段，即第一个 `while` 循环体中 `i++` 部分
	lbu	a5,-17(s0)		// 从帧缓存地址向下第 17 字节无符号取低字节到 a5，即 `a5 = i`
	addiw	a5,a5,1			// a5 = a5 + 1，即 `a5 = i + 1`
	sb	a5,-17(s0)		// 将 a5 的值低字节储存到帧缓存地址向下第 17 字节，即储存变量 `i`
.L2:								// .L2 标号位置
	lbu	a5,-17(s0)		// 从帧缓存向下第17字节加载半字到 a5 寄存器，即 a5 = `i`
	andi	a4,a5,0xff  // 将加载出来的 a5 寄存器与 `0xff` 与，即取低 8bit 储存到 a4 寄存器
	li	a5,8					// 将 a5 寄存器的值设置为 8，用于给循环设置终止条件
	bne	a4,a5,.L4			// `while (i != 8)`，不等于即跳转到 .L4，.L4 即循环体，等于就向下继续执行
	lw	a5,-24(s0)		// 从帧缓存向下第 24 字节取四字节到 a5，即 `a5 = sum`
	sw	a5,-32(s0)		// 将 a5(`sum`) 的值储存到帧缓存向下第 32 字节处，即 `sq = sum`
	sb	zero,-17(s0)	// 将 0 的值储存到帧缓存向下第 17 字节处，即将缓存中变量 `i` 清零，即 `i = 0`
	sw	zero,-24(s0)	// 将 0 的值储存到帧缓存向下第 24 字节处，即将缓存中变量 `sum` 清零，即 `sum = 0`
	j	.L5							// 跳转到 .L5 段
.L7:								// .L7 程序段，即第二个循环体
	lbu	a5,-25(s0)		// 从帧缓存向下第 25 字节无符号低字节加载到 a5，即 `a5 = code`
	sext.w	a4,a5			// 将 a5 符号扩展结果写入 a4，即 `a4 = code`
	lbu	a5,-17(s0)		// 从帧缓存向下第 17 字节无符号低字节加载到 a5，即 `a5 = i`
	sext.w	a5,a5			// 对 a5 做符号扩展
	sraw	a5,a4,a5		// a5 = a4 >>s a5，将 a4 算术右移 a5 位的结果写入 a5，即 `a5 = (i << i)`
	sext.w	a5,a5			// 对 a5 做符号扩展
	andi	a5,a5,1			// 将 a5(`i`) 与 1 相与存到 a5，即得到 `a5 = (1 << i)`
	sext.w	a5,a5			// 对 a5 做符号扩展
	beq	a5,zero,.L6		// `if (code & (1 << i))`，不为0则跳转到 .L6
	lbu	a5,-17(s0)		// 从帧缓存地址向下第 17 字节无符号取低字节到 a5，即 `a5 = i`
	sext.w	a5,a5			// 对 a5 做符号扩展
	mv	a4,a5					// 将 a4 的值设置为 a5，即 `a4 = a5 = i`
	lw	a5,-32(s0)		// 从帧缓存地址向下第 32 字节取四字节到 a4，即 `a4 = sq`
	sllw	a5,a5,a4		// a5 = a4 << a5，即将 a4 逻辑左移 a5 位的结果写入 a5，即 `a5 = sq << i`
	sext.w	a5,a5			// 对 a5 做符号扩展
	lw	a4,-24(s0)		// 从帧缓存地址向下第 24 字节取四字节到 a4，即 `a4 = sum`
	addw	a5,a4,a5		// 将 a4 + a5 的值写入 a5，即 `sum += sq << i`
	sw	a5,-24(s0)		// 将 a5 的值存入帧缓存向下第 24 字节处，即储存 `sum` 到缓存中
.L6:								// .L6 程序段，即第二个 `while` 循环体中 `i++` 部分
	lbu	a5,-17(s0)		// 从帧缓存地址向下第 17 字节无符号取低字节到 a5，即 `a5 = i`
	addiw	a5,a5,1			// a5 = a5 + 1，即 `a5 = i + 1`
	sb	a5,-17(s0)		// 将 a5 的值低字节储存到帧缓存地址向下第 17 字节，即储存变量 `i`
.L5:								// .L5 程序段
	lbu	a5,-17(s0)		// 从帧缓存向下第 17 字节处无符号低字节加载到 a5，即 `a5 = i`
	andi	a4,a5,0xff	// 将 a5 与 0xff 相与的结果写入 a4，即 `a4 = i & 0xff`
	li	a5,16					// 将 a5 的值设置为 16，用于给循环设置终止条件
	bne	a4,a5,.L7			// `while (i != 16)`，不等于即跳转到 .L7
	lw	a5,-24(s0)		// 从帧缓存向下第 24 字节加载四字节到 a5，即 `a5 = sum`
	mv	a0,a5					// 将 a0 的值设置为 a5，即将 `sum` 作为返回值写入返回值寄存器
	ld	s0,24(sp)			// 从栈底向上第 24 字节取八字节写入 s0，即恢复函数调用前的 s0 寄存器的值
	addi	sp,sp,32		// sp 自增 32，即释放申请的 32 字节的栈空间
	jr	ra						// 跳转并链接到上一次调用位置，即返回 `sum` 并跳转到上一调用帧
	.size	_start, .-_start	// 设置 _start 段大小
	.ident	"GCC: (gca312387a) 10.2.0"	// 写明编译器版本信息等
